package com.ruoyi.common.utils.wxpay;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * @author chmj
 * @version V1.0
 * @Package com.ruoyi.common.utils.wxPay
 * @Copyright 2022/4/2 10:45 汇博医疗股份有限公司
 */
@Slf4j
public class WxPayApi {

    /**
     * 统一下单地址
     */
    private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    private static final String APPID = "";
    /**
     * 微信支付分配的商户号
     */
    private static final String mch_id = "1623831810";
    /**
     * 异步接收微信支付结果通知的回调地址
     */
    private static final String notify_url = "";
    /**
     * 微信商户平台-账户设置-安全设置-api安全,配置32位key
     */
    public static String KEY = "";

    /**
     * 统一下单返回预支付id
     *
     * @param body    商品简单描述
     * @param OrderNo 商户订单号
     * @param money   订单总金额，单位为分
     * @param ip      APP和网页支付提交用户端ip Native支付填调用微信支付API的机器IP
     * @param openid  公众号支付时 用户的openid
     * @return prepayId 预支付id
     * @throws Exception
     */
    public static String unifiedH5order(String body, String OrderNo, int money, String ip)
            throws Exception
    {
        String prepayId = "";
        Map<String, String> map = new HashMap<String, String>();
        map.put("appid", APPID);
        map.put("mch_id", mch_id); // 商户号
        map.put("device_info", "WEB"); // PC网页或公众号内支付可以传"WEB"
        map.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串长度要求在32位以内
        map.put("body", body); // 商品简单描述
        map.put("out_trade_no", OrderNo); // 商户订单号
        map.put("total_fee", money + ""); // 订单总金额，单位为分
        map.put("spbill_create_ip", ip); // APP和网页支付提交用户端ip Native支付填调用微信支付API的机器IP
        map.put("notify_url", notify_url); // 订单回调地址
        map.put("trade_type", "NATIVE"); // 交易类型 JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付
//        map.put("openid", "openid");
        map.put("sign", WXPayUtil.generateSignature(map, KEY));
        String dataXML = WXPayUtil.mapToXml(map);
        String resultXMlStr = urlPost(UNIFIEDORDER_URL, dataXML);
        log.info("统一下单返回结果-----------------   " + resultXMlStr);
        Map<String, String> result = WXPayUtil.xmlToMap(resultXMlStr);
        prepayId = result.get("prepay_id");
        if (null == prepayId)
        {
            throw new Exception("获取预支付id失败");
        }
        return prepayId;

    }

    /**
     * 根据预支付id 生成包含所有必须参数的map对象 返回给前端jssdk使用
     *
     * @param prepayId
     * @return
     * @throws Exception
     */
    public Map<String, String> getClientPrepayMap(String prepayId) throws Exception
    {
        Map<String, String> map = new HashMap<String, String>();
        map.put("appId", APPID);
        map.put("timeStamp", String.valueOf(new Date().getTime() / 1000));
        map.put("nonceStr", WXPayUtil.generateNonceStr());
        map.put("package", "prepay_id=" + prepayId);
        map.put("signType", "MD5");
        String sign = WXPayUtil.generateSignature(map, KEY);
        map.put("paySign", sign);
        return map;
    }

    /**
     * 微信支付回调结果参数解析 接收通知成功必须通知微信成功接收通知
     *
     * @param request
     * @return
     * @throws Exception
     */
    public Map<String, String> payCallBack(HttpServletRequest request) throws Exception
    {
        // 读取参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null)
        {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        return WXPayUtil.xmlToMap(sb.toString());

    }

    public static String urlGet(String url) throws Exception
    {
        GetMethod get = new GetMethod(url);
        HttpClient httpClient = new HttpClient();
        get.getParams().setContentCharset("utf-8");
        httpClient.executeMethod(get);
        return get.getResponseBodyAsString();
    }

    @SuppressWarnings("deprecation")
    public static String urlPost(String url, String postBody) throws Exception
    {
        PostMethod post = new PostMethod(url);
        HttpClient httpClient = new HttpClient();
        post.getParams().setContentCharset("utf-8");
        post.setRequestBody(postBody);
        httpClient.executeMethod(post);
        return post.getResponseBodyAsString();
    }
}
